package com.yzq.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yzq.api.aliyunai.AliyunApiAi;
import com.yzq.api.aliyunai.constant.AliyunQianWenModelUrl;
import com.yzq.api.aliyunai.enums.ImageEditFunction;
import com.yzq.api.aliyunai.model.AliyunPictureEditTaskRequest;
import com.yzq.api.aliyunai.model.AliyunTextToImageTaskRequest;
import com.yzq.enums.ErrorCode;
import com.yzq.enums.PictureReviewStatus;
import com.yzq.enums.UserRole;
import com.yzq.exception.BusinessException;
import com.yzq.manager.FilePictureUpload;
import com.yzq.manager.auth.SpaceUserAuthManager;
import com.yzq.model.dto.picture.*;
import com.yzq.model.entity.*;
import com.yzq.model.vo.PictureVO;
import com.yzq.model.vo.UserVO;
import com.yzq.service.CommentsService;
import com.yzq.service.LikesService;
import com.yzq.service.PictureService;
import com.yzq.mapper.PictureMapper;
import com.yzq.service.SpaceService;
import com.yzq.utils.AliyunOSSUtils;
import com.yzq.utils.ThrowUtils;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
* @author yezhi
* @description 针对表【picture(图片)】的数据库操作Service实现
* @createDate 2025-07-02 07:13:48
*/
@Slf4j
@Service
public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture>
    implements PictureService{

    @Resource
    private FilePictureUpload filePictureUpload;

    @Resource
    private PictureMapper pictureMapper;

    @Resource
    private AliyunOSSUtils aliyunOSSUtils;

    @Resource
    private UserServiceImpl userService;

    @Resource
    private LikesService likesService;

    @Resource
    private CommentsService commentsService;

    @Resource
    private SpaceService spaceService;

    @Resource
    private TransactionTemplate transactionTemplate;

    @Resource
    private AliyunApiAi aliyunApiAi;
    @Autowired
    private SpaceUserAuthManager spaceUserAuthManager;

    @Override
    public String uploadPictureToAliyun(MultipartFile file) throws Exception {
        ThrowUtils.throwIf(file == null, ErrorCode.BAD_REQUEST);
        // 上传文件到 OSS
        String url = filePictureUpload.uploadLocalFile(file,null);
        log.info("上传图片成功: {}", url);
        // 使用ScheduledExecutorService实现延迟任务，更加优雅和可控
        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.schedule(() -> {
            try {
                aliyunOSSUtils.deleteFile(url);
                log.info("图片已成功删除: {}", url);
            } catch (Exception e) {
                log.error("删除图片失败: {}, 错误: {}", url, e.getMessage());
            } finally {
                // 关闭线程池
                scheduler.shutdown();
            }
        }, 10, TimeUnit.MINUTES);
        return url;
    }

    @Override
    public PictureVO uploadPicture(MultipartFile  file, PictureUploadRequest pictureUploadRequest, HttpServletRequest request) throws Exception {
        // 校验上传请求
        log.info("上传图片: {}", pictureUploadRequest);
        ThrowUtils.throwIf(pictureUploadRequest == null, ErrorCode.BAD_REQUEST);

        // 获取当前用户
        UserVO user = userService.getCurrentUser(request);

        Long spaceId = pictureUploadRequest.getSpaceId();
        if(spaceId != null) {
            Space space = spaceService.getById(spaceId);
            ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND, "空间不存在");
            // 必须空间创建人 / 管理员 才能上传
            if (!userService.isAdmin(request) && !user.getId().equals(space.getUserId())) {
                throw new BusinessException(ErrorCode.UNAUTHORIZED, "无权限上传");
            }
            if(space.getTotalCount() >= space.getMaxCount()) {
                throw new BusinessException(ErrorCode.FORBIDDEN, "空间条数不足");
            }

            if(space.getTotalSize() >= space.getMaxSize()) {
                throw new BusinessException(ErrorCode.FORBIDDEN, "空间大小不足");
            }
        }

        // 上传文件到 OSS
        String url = filePictureUpload.uploadLocalFile(file,pictureUploadRequest.getSpaceId());
        // 获取图片信息
        PictureAnalysisResult analysisResult = aliyunOSSUtils.getImage(url);
        log.info("图片信息: {}", analysisResult);
        // 保存图片信息到数据库
        Picture picture = PictureAnalysisResult.toPicture(analysisResult);
        log.info("保存图片信息: {}", picture);
        picture.setIntroduction(pictureUploadRequest.getIntroduction());
        picture.setClassifyId(pictureUploadRequest.getClassifyId());
        if(pictureUploadRequest.getTags() != null) {
            picture.setTags(listToString(pictureUploadRequest.getTags()));
        }

        picture.setUserId(user.getId());
        if(!StrUtil.isBlank(pictureUploadRequest.getName())) {
            picture.setName(pictureUploadRequest.getName());
        }
        picture.setCreateTime(new Date());
        picture.setUpdateTime(picture.getCreateTime());
        picture.setEditTime(picture.getCreateTime());
        picture.setSpaceId(spaceId);
        boolean admin = userService.isAdmin(request);
        if(admin) {
            picture.setReviewStatus(1);
        } else {
            picture.setReviewStatus(0);
        }

        // 开启事务
        transactionTemplate.execute(status -> {
            int insert = pictureMapper.insert(picture);
            if (insert != 1) {
                throw new BusinessException(ErrorCode.INTERNAL_SERVER_ERROR,"图片保存失败");
            }
            if (spaceId != null) {
                boolean update = spaceService.lambdaUpdate()
                        .eq(Space::getId, spaceId)
                        .setSql("total_size = total_size + " + picture.getPicSize())
                        .setSql("total_count = total_count + 1")
                        .update();
                ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "额度更新失败");
            }
            return picture;
        });

        PictureVO pictureVO = new PictureVO();
        BeanUtil.copyProperties(picture, pictureVO);

        // 获取当前登录用户
        UserVO currentUser = userService.getCurrentUser(request);
        pictureVO.setUser(currentUser);
        return pictureVO;
    }

    /**
     *  图片URL上传
     * @param pictureUrlUploadRequest 图片URL上传请求
     * @param request 请求
     * @return 图片上传结果
     * @throws Exception 当 URL 校验不通过或上传过程中出现异常时抛出
     */
    @Override
    public PictureVO uploadPictureByUrl(PictureUrlUploadRequest pictureUrlUploadRequest, HttpServletRequest request) throws Exception {

        String s = filePictureUpload.uploadUrl(pictureUrlUploadRequest.getFileUrl(), pictureUrlUploadRequest.getSpaceId());
        PictureAnalysisResult analysisResult = aliyunOSSUtils.getImage(s);
        log.info("图片信息: {}", analysisResult);

        // 获取当前用户
        UserVO user = userService.getCurrentUser(request);

        Long spaceId = pictureUrlUploadRequest.getSpaceId();
        if(spaceId != null) {
            Space space = spaceService.getById(spaceId);
            ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND, "空间不存在");
            // 必须空间创建人 / 管理员 才能上传
            log.info("空间创建人: {}", space.getUserId());
            log.info("当前用户: {}", user.getId());
            if (!userService.isAdmin(request) && !user.getId().equals(space.getUserId())) {
                throw new BusinessException(ErrorCode.UNAUTHORIZED, "无权限上传");
            }
        }
        // 保存图片信息到数据库
        Picture picture = PictureAnalysisResult.toPicture(analysisResult);
        if(!StrUtil.isBlank(pictureUrlUploadRequest.getPicName())) {
            picture.setName(pictureUrlUploadRequest.getPicName());
        }
        picture.setIntroduction(pictureUrlUploadRequest.getIntroduction());
        picture.setClassifyId(pictureUrlUploadRequest.getClassifyId());
        if(pictureUrlUploadRequest.getTags() != null) {
            picture.setTags(listToString(pictureUrlUploadRequest.getTags()));
        }


        picture.setUserId(user.getId());
        picture.setCreateTime(new Date());
        picture.setUpdateTime(picture.getCreateTime());
        picture.setEditTime(picture.getCreateTime());
        picture.setSpaceId(spaceId);
        boolean admin = userService.isAdmin(request);
        if(admin) {
            picture.setReviewStatus(1);
        } else {
            picture.setReviewStatus(0);
        }
        // 开启事务
        transactionTemplate.execute(status -> {
            int insert = pictureMapper.insert(picture);
            if (insert != 1) {
                throw new BusinessException(ErrorCode.INTERNAL_SERVER_ERROR,"图片保存失败");
            }
            if (spaceId != null) {
                boolean update = spaceService.lambdaUpdate()
                        .eq(Space::getId, spaceId)
                        .setSql("total_size = total_size + " + picture.getPicSize())
                        .setSql("total_count = total_count + 1")
                        .update();
                ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "额度更新失败");
            }
            return picture;
        });
        PictureVO pictureVO = new PictureVO();
        BeanUtil.copyProperties(picture, pictureVO);
        UserVO currentUser = userService.getCurrentUser(request);
        pictureVO.setUser(currentUser);
        return pictureVO;
    }

    /**
     * 删除图片
     * @param pictureDeleteRequest 图片删除请求
     * @return 是否删除成功
     */
    @Override
    public Boolean deletePicture(PictureDeleteRequest pictureDeleteRequest, HttpServletRequest request) {
        if (pictureDeleteRequest == null || pictureDeleteRequest.getId() == null) {
            throw new BusinessException(ErrorCode.BAD_REQUEST);
        }
        Picture picture = getById(pictureDeleteRequest.getId());

//        // 检查权限
//        checkPictureAuth(picture, request);
        // 开启事务
        transactionTemplate.execute(status -> {
            int deleteResult = pictureMapper.deleteById(pictureDeleteRequest.getId());
            ThrowUtils.throwIf(deleteResult!=1, ErrorCode.OPERATION_ERROR);
            // 释放额度
            Long spaceId = picture.getSpaceId();
            if (spaceId != null) {
                boolean update = spaceService.lambdaUpdate()
                        .eq(Space::getId, spaceId)
                        .setSql("total_size = total_size - " + picture.getPicSize())
                        .setSql("total_count = total_count - 1")
                        .update();
                ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "额度更新失败");
            }
            return true;
        });

        return true;
    }

    /**
     * 修改图片
     * @param pictureUpdateRequest 图片修改请求
     * @param  request HttpServletRequest
     * @return 是否修改成功
     */
    @Override
    public Boolean updatePicture(PictureUpdateRequest pictureUpdateRequest, HttpServletRequest request) {
        if (pictureUpdateRequest == null || pictureUpdateRequest.getId() == null) {
            throw new BusinessException(ErrorCode.BAD_REQUEST);
        }
        // 获取当前用户
        UserVO currentUser = userService.getCurrentUser(request);
        if(pictureUpdateRequest.getUserId() != null && !pictureUpdateRequest.getUserId().equals(currentUser.getId())) {
            throw new BusinessException(ErrorCode.UNAUTHORIZED);
        }

        // 获取旧图片
        Picture picture = getById(pictureUpdateRequest.getId());
        BeanUtil.copyProperties(pictureUpdateRequest, picture); // 复制属性
        picture.setTags(listToString(pictureUpdateRequest.getTags()));
        if(pictureUpdateRequest.getUrl() != null) {
            picture.setThumbnailUrl(pictureUpdateRequest.getUrl() + "?x-oss-process=image/quality,q_60");
        }
        picture.setUpdateTime(new Date());
        picture.setEditTime(picture.getUpdateTime());
        boolean admin = userService.isAdmin(request);
        if(admin) {
            picture.setReviewStatus(1);
        } else {
            picture.setReviewStatus(0);
        }

        // 请求参数存在空间id，必须和原图片的空间id一致
        if (pictureUpdateRequest.getSpaceId() != null && !pictureUpdateRequest.getSpaceId().equals(picture.getSpaceId())) {
            throw new BusinessException(ErrorCode.BAD_REQUEST, "空间id不一致");
        }

        int updateResult = pictureMapper.updateById(picture);
        return updateResult == 1;
    }

    /**
     * 获取图片列表
     * @param pictureQueryRequest 图片查询请求
     * @return 图片列表
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Page<PictureVO> getPictureList(PictureQueryRequest pictureQueryRequest) {
        Page<Picture> page = new Page<>(pictureQueryRequest.getPageNum(), pictureQueryRequest.getPageSize());
        QueryWrapper<Picture> pictureQueryWrapper = getPictureQueryWrapper(pictureQueryRequest);

        Long spaceId = pictureQueryRequest.getSpaceId();
        if(spaceId == null) {
            // 只获取审核通过的图片
            pictureQueryWrapper.eq(true, "review_status", 1);
        }

        Page<Picture> picturePage = pictureMapper.selectPage(page, pictureQueryWrapper);

        // 将得到的数据转换成VO
        Page<PictureVO> pictureVOPage = new Page<>(pictureQueryRequest.getPageNum(), pictureQueryRequest.getPageSize());
        pictureVOPage.setRecords(picturePage.getRecords().stream().map(picture -> {
            PictureVO pictureVO = new PictureVO();
            BeanUtils.copyProperties(picture, pictureVO);
            // 查找用户信息
            User user = userService.getById(picture.getUserId());
            if (user != null) {
                pictureVO.setUser(UserVO.toVO(user));
            }
            pictureVO.setTags(stringToList(picture.getTags()));
            // 查询点赞数
            extracted(picture, pictureVO);
            return pictureVO;
        }).toList());
        pictureVOPage.setTotal(picturePage.getTotal());
        pictureVOPage.setPages(picturePage.getPages());
        return pictureVOPage;
    }


    /**
     * 获取查询条件
     * @param pictureQueryRequest 查询条件
     * @return 查询条件
     */
    private static @NotNull QueryWrapper<Picture> getPictureQueryWrapper(PictureQueryRequest pictureQueryRequest) {
        String searchQuery = pictureQueryRequest.getSearchQuery();
        Long classifyId = pictureQueryRequest.getClassifyId();
        Long spaceId = pictureQueryRequest.getSpaceId();
        Boolean nullSpaceId = pictureQueryRequest.getNullSpaceId();
        QueryWrapper<Picture> pictureQueryWrapper = new QueryWrapper<>();
        Date startEditTime = pictureQueryRequest.getStartEditTime();
        Date endEditTime = pictureQueryRequest.getEndEditTime();
        if(StrUtil.isNotBlank(searchQuery)) {
            try {
                Long id = Long.valueOf(searchQuery);
                pictureQueryWrapper.eq("id", id);
            } catch (Exception e) {
                pictureQueryWrapper.and(wrapper ->
                        wrapper.like("name", searchQuery)
                                .or().like("tags", searchQuery)
                                .or().like("introduction", searchQuery)
                                .or().like("url", searchQuery)
                                .or().like("pic_color", searchQuery)
                );
            }
        }
        if(ObjUtil.isNotNull(classifyId)) {
            pictureQueryWrapper.eq("classify_id", classifyId);
        }


        pictureQueryWrapper.ge(ObjUtil.isNotEmpty(startEditTime), "edit_time", startEditTime);
        pictureQueryWrapper.lt(ObjUtil.isNotEmpty(endEditTime), "edit_time", endEditTime);


        pictureQueryWrapper.eq(ObjUtil.isNotEmpty(spaceId), "space_id", spaceId);
        pictureQueryWrapper.isNull(nullSpaceId, "space_id");

        // 处理排序条件
        String sortField = pictureQueryRequest.getSortField();
        String sortOrder = pictureQueryRequest.getSortOrder();
        if (StrUtil.isNotBlank(sortField) && StrUtil.isNotBlank(sortOrder)) {
            boolean isAsc = "ascend".equalsIgnoreCase(sortOrder);
            pictureQueryWrapper.orderBy(true, isAsc, sortField);
        }

        return pictureQueryWrapper;
    }


    /**
     * 获取根据 id 查找图片
     * @param id 图片 id
     * @return  图片
     */
    @Override
    public PictureVO getPictureById(Long id, HttpServletRequest request) {
        if (id == null) {
            throw new BusinessException(ErrorCode.BAD_REQUEST);
        }


        Picture picture = pictureMapper.selectById(id);
        if (picture == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "图片不存在");
        }

//        if(picture.getSpaceId() != null) {
//            checkPictureAuth(picture, request);
//        }

        PictureVO pictureVO = new PictureVO();
        BeanUtil.copyProperties(picture, pictureVO);
        // 处理标签
        pictureVO.setTags(stringToList(picture.getTags()));
        pictureVO.setUser(UserVO.toVO(userService.getUserById(picture.getUserId())));

        //获取当前用户
        UserVO currentUser = userService.getCurrentUser(request);
        if(currentUser != null) {
            // 查询点赞列表是否已经点赞
            QueryWrapper<Likes> likeQueryWrapper = new QueryWrapper<>();
            likeQueryWrapper.eq("user_id", currentUser.getId())
                            .eq("picture_id", picture.getId());
            pictureVO.setIsLiked(likesService.isLike(likeQueryWrapper));
        } else {
            pictureVO.setIsLiked(false);
        }

        extracted(picture, pictureVO);
        Long spaceId = picture.getSpaceId();
        Space space = null;
        if(spaceId != null) {
            space = spaceService.getById(spaceId);

        }
        List<String> permissionList = spaceUserAuthManager.getPermissionList(space, currentUser);
        pictureVO.setPermissionList(permissionList);

        return pictureVO;
    }


    /**
     * 设置图片点赞数和评论数
     * @param picture  图片
     * @param pictureVO 图片VO
     */
    private void extracted(Picture picture, PictureVO pictureVO) {
        // 查询点赞数
        QueryWrapper<Likes> likeQueryWrapper = new QueryWrapper<>();
        likeQueryWrapper.eq("picture_id", picture.getId());
        long likeCount = likesService.count(likeQueryWrapper);
        pictureVO.setLikeCount(likeCount);

        // 查询评论数
        QueryWrapper<Comments> commentQueryWrapper = new QueryWrapper<>();
        commentQueryWrapper.eq("picture_id", picture.getId());
        long commentCount = commentsService.count(commentQueryWrapper);
        pictureVO.setCommentCount(commentCount);
    }

    /**
     * 管理员获取图片列表
     * @param pictureQueryRequest 图片查询请求
     * @return 图片列表
     */
    @Override
    public Page<Picture> getPictureListByAdmin(PictureQueryRequest pictureQueryRequest) {
        Page<Picture> page = new Page<>(pictureQueryRequest.getPageNum(), pictureQueryRequest.getPageSize());
        QueryWrapper<Picture> pictureQueryWrapper = getPictureQueryWrapper(pictureQueryRequest);
        // 查找审核
        pictureQueryWrapper.eq(ObjUtil.isNotNull(pictureQueryRequest.getReviewStatus()), "review_status", pictureQueryRequest.getReviewStatus());
        return pictureMapper.selectPage(page, pictureQueryWrapper);
    }

    /**
     *
     * @param pictureReviewRequest 图片审核请求
     * @param request 请求
     * @return 是否审核成功
     */
    @Override
    public Boolean reviewPicture(PictureReviewRequest pictureReviewRequest, HttpServletRequest request) {
        if (pictureReviewRequest == null || pictureReviewRequest.getId() == null) {
            throw new BusinessException(ErrorCode.BAD_REQUEST);
        }
        // 获取当前用户
        UserVO currentUser = userService.getCurrentUser(request);
        if (!currentUser.getUserRole().equals(UserRole.ADMIN.getCode())) {
            throw new BusinessException(ErrorCode.UNAUTHORIZED);
        }
        PictureReviewStatus reviewStatus = PictureReviewStatus.getByCode(pictureReviewRequest.getReviewStatus());
        if (reviewStatus == null) {
            throw new BusinessException(ErrorCode.BAD_REQUEST, "图片审核状态错误");
        }
        // 获取图片
        Picture picture = pictureMapper.selectById(pictureReviewRequest.getId());
        if (picture == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "图片不存在");
        }
        picture.setReviewStatus(pictureReviewRequest.getReviewStatus());
        picture.setReviewMessage(pictureReviewRequest.getReviewMessage());
        picture.setReviewerId(currentUser.getId());
        picture.setReviewTime(new Date());
        int updateResult = pictureMapper.updateById(picture);
        return updateResult == 1;
    }


    /**
     * List<String> 转换位 JSON
     * @param list List<String>
     * @return JSON
     */
    private static String listToString(List<String> list) {
        return JSON.toJSONString(list);
    }

    /**
     * 批量抓取图片
     * @param pictureUploadByBatchRequest 图片批量上传请求
     * @param request 请求
     * @return 批量上传结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer uploadPictureByBatch(PictureUploadByBatchRequest pictureUploadByBatchRequest, HttpServletRequest request) throws Exception {
        if(pictureUploadByBatchRequest == null) {
            throw new BusinessException(ErrorCode.BAD_REQUEST);
        }
        ThrowUtils.throwIf(pictureUploadByBatchRequest.getSearchText() == null, ErrorCode.BAD_REQUEST);
        ThrowUtils.throwIf(pictureUploadByBatchRequest.getBatchNum() == null, ErrorCode.BAD_REQUEST);

        String searchText = pictureUploadByBatchRequest.getSearchText();
        Integer batchNum = pictureUploadByBatchRequest.getBatchNum();
        log.info("开始批量抓取图片,搜索关键字为:{},批量数量为:{}", searchText, batchNum);

        //要抓取的地址
        String format = String.format("https://cn.bing.com/images/async?q=%s&mmasync=1", searchText);
        Document document;
        try {
            document = Jsoup.connect(format).get();
        } catch (IOException e) {
            log.error("获取图片失败");
            throw new BusinessException(ErrorCode.SERVICE_UNAVAILABLE, "获取图片失败");
        }
        Element div = document.getElementsByClass("dgControl").first();
        if(ObjUtil.isNull(div)) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "未找到图片");
        }
        Elements select = div.select("img.mimg");
        int uploadNum = 0;
        for (Element element : select) {
            String src = element.attr("src");
            if(StrUtil.isBlank( src)) {
                log.info("图片地址为空");
                continue;
            }
            int i = src.indexOf("?");
            if(i > -1) {
                src = src.substring(0, i);
            }
            // 上传图片
            PictureUrlUploadRequest pictureUrlUploadRequest = new PictureUrlUploadRequest();
            pictureUrlUploadRequest.setFileUrl(src);
            // 设置图片名称（关键字 + 日期 + 第几个）
            pictureUrlUploadRequest.setPicName( searchText + DateUtil.format(new Date(), "yyyyMMdd") + (i + 1));
            log.info("图片：{}",pictureUrlUploadRequest);
            PictureVO pictureVO = uploadPictureByUrl(pictureUrlUploadRequest, request);
            log.info("开始上传图片：{}", pictureVO);
            uploadNum++;
            log.info("上传图片数量：{}", uploadNum);
            if (uploadNum >= batchNum) {
                break;
            }
        }
        return uploadNum;
    }

    /**
     * String 转换为 List<String>
     * @param str String
     * @return List<String>
     */
    private static List<String> stringToList(String str) {
        return JSON.parseArray(str, String.class);
    }

    @Override
    public void downloadPicture(PictureDownloadRequest pictureDownloadRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(pictureDownloadRequest == null, ErrorCode.BAD_REQUEST);
        ThrowUtils.throwIf(ObjUtil.isNull(pictureDownloadRequest.getId()), ErrorCode.BAD_REQUEST);
        // 是否登录
        UserVO currentUser = userService.getCurrentUser(request);
        ThrowUtils.throwIf(currentUser == null, ErrorCode.UNAUTHORIZED);
        Picture picture = pictureMapper.selectById(pictureDownloadRequest.getId());
        ThrowUtils.throwIf(picture == null, ErrorCode.NOT_FOUND);
        picture.setDownloadCount(picture.getDownloadCount() + 1);
        int updateResult = pictureMapper.updateById(picture);
        ThrowUtils.throwIf(updateResult != 1, ErrorCode.SERVICE_UNAVAILABLE);
    }

//    @Override
//    public void checkPictureAuth(Picture picture, HttpServletRequest request) {
//        Long spaceId = picture.getSpaceId();
//        // 获取当前用户
//        UserVO currentUser = userService.getCurrentUser(request);
//        ThrowUtils.throwIf(currentUser == null, ErrorCode.UNAUTHORIZED);
//        if (spaceId == null) {
//            // 公共图库，仅本人或管理员可操作
//            if (!picture.getUserId().equals(currentUser.getId()) && !userService.isAdmin(request)) {
//                throw new BusinessException(ErrorCode.UNAUTHORIZED);
//            }
//        } else {
//            // 私有空间，仅空间管理员可操作
//            if (!picture.getUserId().equals(currentUser.getId())) {
//                throw new BusinessException(ErrorCode.UNAUTHORIZED);
//            }
//        }
//    }

    /**
     * 批量修改图片信息
     * @param pictureEditByBatchRequest 图片批量修改请求
     * @param request 请求
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editPictureByBatch(PictureEditByBatchRequest pictureEditByBatchRequest, HttpServletRequest request) {
        List<Long> pictureIdList = pictureEditByBatchRequest.getPictureIdList();
        Long spaceId = pictureEditByBatchRequest.getSpaceId();
        Long classifyId = pictureEditByBatchRequest.getClassifyId();
        List<String> tags = pictureEditByBatchRequest.getTags();

        UserVO currentUser = userService.getCurrentUser(request);

        // 1. 校验参数
        ThrowUtils.throwIf(spaceId == null || CollUtil.isEmpty(pictureIdList), ErrorCode.BAD_REQUEST);
        ThrowUtils.throwIf(currentUser == null, ErrorCode.FORBIDDEN_USER_NOT_LOGIN);
        // 2. 校验空间权限
        Space space = spaceService.getById(spaceId);
        ThrowUtils.throwIf(space == null, ErrorCode.UNAUTHORIZED, "空间不存在");
        if (!currentUser.getId().equals(space.getUserId())) {
            throw new BusinessException(ErrorCode.UNAUTHORIZED, "没有空间访问权限");
        }

        // 3. 查询指定图片，仅选择需要的字段
        List<Picture> pictureList = this.lambdaQuery()
                .select(Picture::getId, Picture::getSpaceId)
                .eq(Picture::getSpaceId, spaceId)
                .in(Picture::getId, pictureIdList)
                .list();

        if (pictureList.isEmpty()) {
            return;
        }

        //5. 批量重命名
        String nameRule = pictureEditByBatchRequest.getNameRule();
        fillPictureWithNameRule(pictureList, nameRule);

        // 4. 更新分类和标签
        pictureList.forEach(picture -> {
            if (ObjUtil.isNotNull(classifyId)) {
                picture.setClassifyId(classifyId);
            }
            if (CollUtil.isNotEmpty(tags)) {
                picture.setTags(JSONUtil.toJsonStr(tags));
            }
        });
        // 6. 批量更新
        boolean result = this.updateBatchById(pictureList);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
    }


    /**
     * nameRule 格式：图片{序号}
     *
     * @param pictureList 图片列表
     * @param nameRule 图片名称规则
     */
    private void fillPictureWithNameRule(List<Picture> pictureList, String nameRule) {
        if (CollUtil.isEmpty(pictureList) || StrUtil.isBlank(nameRule)) {
            return;
        }
        long count = 1;
        try {
            for (Picture picture : pictureList) {
                String pictureName = nameRule.replaceAll("\\{序号}", String.valueOf(count++));
                picture.setName(pictureName);
            }
        } catch (Exception e) {
            log.error("名称解析错误", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "名称解析错误");
        }
    }

    /**
     * 创建文生图任务
     * @param textToImageRequest 文生图请求
     */
    @Override
    public String createTextToImageTask(TextToImageRequest textToImageRequest) {
        // 1. 校验参数
        ThrowUtils.throwIf(textToImageRequest == null, ErrorCode.BAD_REQUEST);
        ThrowUtils.throwIf(StrUtil.isBlank(textToImageRequest.getPrompt()), ErrorCode.BAD_REQUEST);

        String prompt = textToImageRequest.getPrompt().trim();
        ThrowUtils.throwIf(prompt.isEmpty(), ErrorCode.BAD_REQUEST, "请输入有效的提示语");
        ThrowUtils.throwIf(prompt.length() > 100, ErrorCode.BAD_REQUEST, "提示语过长");
        Integer n = textToImageRequest.getN();
        String size = textToImageRequest.getSize();

        //3. 创建文生图任务
        AliyunTextToImageTaskRequest aliyunTextToImageTaskRequest = new AliyunTextToImageTaskRequest();
        AliyunTextToImageTaskRequest.Input input = new AliyunTextToImageTaskRequest.Input();
        AliyunTextToImageTaskRequest.Parameters parameters = new AliyunTextToImageTaskRequest.Parameters();
        input.setPrompt(prompt);
        parameters.setSize(size);
        parameters.setN(n);
        aliyunTextToImageTaskRequest.setParameters(parameters);
        aliyunTextToImageTaskRequest.setInput(input);

        String textToImageTask = aliyunApiAi.createTask(aliyunTextToImageTaskRequest, AliyunQianWenModelUrl.CREATE_TEXT_IMAGE_TASK_URL);

        ThrowUtils.throwIf(textToImageTask == null, ErrorCode.OPERATION_ERROR, "文生图任务创建失败");
        return textToImageTask;
    }

    @Override
    public String createPictureEditTask(AIImageEditRequest pictureEditRequest) {
        ThrowUtils.throwIf(pictureEditRequest == null, ErrorCode.BAD_REQUEST);
        ThrowUtils.throwIf(StrUtil.isBlank(pictureEditRequest.getPrompt()), ErrorCode.BAD_REQUEST);
        ThrowUtils.throwIf(StrUtil.isBlank(pictureEditRequest.getBaseImageUrl()), ErrorCode.BAD_REQUEST);
        ThrowUtils.throwIf(ObjUtil.isNull(pictureEditRequest.getFunction()), ErrorCode.BAD_REQUEST);
        String prompt = pictureEditRequest.getPrompt().trim();
        ThrowUtils.throwIf(prompt.isEmpty(), ErrorCode.BAD_REQUEST, "请输入有效的提示语");
        ThrowUtils.throwIf(prompt.length() > 100, ErrorCode.BAD_REQUEST, "提示语过长");

        String baseImageUrl = pictureEditRequest.getBaseImageUrl();
        ImageEditFunction function = pictureEditRequest.getFunction();
        Integer n = pictureEditRequest.getN();
        Float leftScale = pictureEditRequest.getLeftScale();
        Float rightScale = pictureEditRequest.getRightScale();
        Float topScale = pictureEditRequest.getTopScale();
        Float bottomScale = pictureEditRequest.getBottomScale();

        AliyunPictureEditTaskRequest aliyunImageEditTaskRequest = new AliyunPictureEditTaskRequest();
        AliyunPictureEditTaskRequest.Input input = new AliyunPictureEditTaskRequest.Input();
        input.setFunction(function.getFunctionName());
        input.setBaseImageUrl(baseImageUrl);
        input.setPrompt(prompt);

        AliyunPictureEditTaskRequest.Parameters parameters = new AliyunPictureEditTaskRequest.Parameters();
        parameters.setN(n);
        if(function.equals(ImageEditFunction.EXPAND)) {
            parameters.setLeftScale(leftScale);
            parameters.setRightScale(rightScale);
            parameters.setTopScale(topScale);
            parameters.setBottomScale(bottomScale);
        }

       aliyunImageEditTaskRequest.setInput(input);
       aliyunImageEditTaskRequest.setParameters(parameters);

       String pictureEditTask = aliyunApiAi.createTask(aliyunImageEditTaskRequest, AliyunQianWenModelUrl.CREATE_PICTURE_EDIT_TASK_URL);
       ThrowUtils.throwIf(pictureEditTask == null, ErrorCode.OPERATION_ERROR, "图片编辑任务创建失败");
       return pictureEditTask;
    }

    /**
     * 修改用户头像
     * @param file 文件
     * @param request 请求
     */
    @Override
    public void changeUserAvatar(MultipartFile file, HttpServletRequest request) throws Exception {
        ThrowUtils.throwIf(file == null, ErrorCode.BAD_REQUEST);
        UserVO loginUser = userService.getCurrentUser(request);
        Long userId = loginUser.getId();
        User user = userService.getUserById(userId);
        String url = filePictureUpload.uploadLocalFile(file,null);
        user.setUserAvatar(url);
        userService.updateById(user);
    }
}




